package cn.qicaiwang.open.websocket.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.qicaiwang.open.common.entity.LoginUser;
import cn.qicaiwang.open.common.enums.ResultStatusCodeEnum;
import cn.qicaiwang.open.common.response.ResponseResult;
import cn.qicaiwang.open.common.utils.jwt.JwtTokenUtil;
import cn.qicaiwang.open.websocket.common.Constant;

import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * WebSocket握手拦截器
 * @since 2022年9月16日16:57:52
 */
@Slf4j
@Component
public class CrmHandshakeInterceptor implements HandshakeInterceptor {
    /**
     * 初次握手访问前
     * @param request
     * @param response
     * @param webSocketHandler
     * @param attributes
     * @return
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler, Map<String, Object> attributes) throws IOException {
        log.info("HandshakeInterceptor beforeHandshake start...");
        if (request instanceof ServletServerHttpRequest) {
            HttpServletRequest req = ((ServletServerHttpRequest) request).getServletRequest();
            HttpServletResponse res = ((ServletServerHttpResponse) response).getServletResponse();
            String authorization = req.getHeader("Sec-WebSocket-Protocol");
            log.info("Authorization = {}", authorization);
            if(StrUtil.isNotBlank(authorization)){
                Boolean expired = false;
                LoginUser loginUser = null;
                try {
                    loginUser = JwtTokenUtil.getLoginUserFromToken(authorization);//根据token获取user
                } catch (ExpiredJwtException e) {
                    expired = true;
                }
                if (expired) {
                    res.setContentType("application/json;charset=UTF-8");
                    res.getWriter().write(JSON.toJSONString(ResponseResult.error(ResultStatusCodeEnum.TOKEN_EXPIRED)));
                    return false;
                }
                if (loginUser != null) {
                    attributes.put(Constant.WS_CONTEXT_HOLDER, loginUser);
                }
            }
        }
        return true;
    }
 
    /**
     * 初次握手访问后，将前端自定义协议头Sec-WebSocket-Protocol原封不动返回回去，否则会报错
     * @param request
     * @param serverHttpResponse
     * @param webSocketHandler
     * @param e
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
        log.info("HandshakeInterceptor afterHandshake start...");
        HttpServletRequest httpRequest = ((ServletServerHttpRequest) request).getServletRequest();
        HttpServletResponse httpResponse = ((ServletServerHttpResponse) serverHttpResponse).getServletResponse();
        if (StrUtil.isNotBlank(httpRequest.getHeader("Sec-WebSocket-Protocol"))) {
            httpResponse.addHeader("Sec-WebSocket-Protocol", httpRequest.getHeader("Sec-WebSocket-Protocol"));
        }
        log.info("HandshakeInterceptor afterHandshake end...");
    }
 
}